{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Reconfiguring a workflow for hybrid compute environments\n",
    "One of the great things about cloud is the ability to construct hybrid GPU-CPU environments for efficient processing. This, however can bring challenges around design and configuration of bulk processing flows.\n",
    "\n",
    "Ideally our signal processing experts and data scientists can design a workflow with a limited, but representative, subset of the data. They can do this work locally on laptop or desktop. When we have a signal processing flow in place, we want to transfer this to the most efficient bulk processing scheme on the available hardware.\n",
    "\n",
    "Although there is a useful [comparison table between numpy and cupy](https://docs-cupy.chainer.org/en/stable/reference/comparison.html) it is cumbersome to continually be cross-referencing that against the [distpy Command Reference](https://github.com/Schlumberger/distpy/wiki/Command-Dictionary). We want the processing experts to concentrate on developing workflows, and the cloud experts to concentrate on deployment. We also want a common view for discussion at daily stand-ups.\n",
    "\n",
    "In this tutorial we will show how a complex **distpy** signal processing chain can be reconfigured to a hybrid GPU-CPU environment.\n",
    "\n",
    "At the end of this tutorial you will know how to:\n",
    "1. Autodocument a flow and how to customize self-documented flows\n",
    "2. Create the developer view for analysing an existing flow\n",
    "3. How to reconfigure flows for GPU-CPU\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preliminaries\n",
    "This flow requires **distpy** version 1.23.0 or higher. The cell below will show which version you are using, you can update via \n",
    "`pip install --upgrade distpy`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.23.0\n"
     ]
    }
   ],
   "source": [
    "import distpy\n",
    "print(distpy.__version__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## A more complicated flow\n",
    "\n",
    "If you have already worked through the [seismic quicklook plots](https://github.com/Schlumberger/distpy/wiki/User-Tutorial-:-distpy-on-linux), \n",
    "[noise log](https://github.com/Schlumberger/distpy/wiki/User-Tutorial-:--distpy-on-cloud), and [event detection](https://github.com/Schlumberger/distpy/wiki/User-Tutorial-:-dispty-on-windows)\n",
    "tutorials, the following workflow is the amalgamation of all 3 and provides an indication of the type of bulk processing flows associated with \n",
    "Distributed Acoustic Sensing (DAS) and the rich array of results that can be created.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "myFlow = {\n",
    "\"document\" : 0,\n",
    "\"description\" : \"A more complex example of a DAS processing flow\",\n",
    "\"command_list\" :\n",
    "[\n",
    " { \"name\" : \"butter\",         \"uid\" :  1, \"in_uid\" : 0, \"type\" : \"lowpass\", \"freq\" : 200 },\n",
    " { \"name\" : \"butter\",         \"uid\" :  2, \"in_uid\" : 1, \"type\" : \"highpass\", \"freq\" : 5 },\n",
    " { \"name\" : \"thumbnail\",      \"uid\" :  3, \"in_uid\" : 2, \"directory_out\" : \"png\" },\n",
    " { \"name\" : \"fft\",            \"uid\" :  4, \"in_uid\" :  0, \"axis\" : 1 },\n",
    " { \"name\" : \"rms_from_fft\",   \"uid\" :  5, \"in_uid\" :  4, \"low_freq\" : 0, \"high_freq\" : -1 },\n",
    " { \"name\" : \"multiple_calcs\", \"uid\" :  6, \"in_uid\" :  4,   \"func\" : \"te_from_fft\",     \"low_freq\" : [200,600,1000], \"high_freq\" : [-1,-1,-1] },\n",
    " { \"name\" : \"write_witsml\",   \"uid\" :  7, \"in_uid\" :  6, \"directory_out\" : \"NoiseLog\", \"low_freq\" : [200,600,1000], \"high_freq\" : [-1,-1,-1],  \"gather_uids\" : [5], \"data_style\" : \"NoiseLog\" },\n",
    " { \"name\" : \"fft\",            \"uid\" : 8, \"in_uid\" :  4, \"axis\" : 0},\n",
    " { \"name\" : \"velocity_map\",   \"uid\" : 9, \"in_uid\" :  8},\n",
    " { \"name\" : \"velocity_mask\",  \"uid\" : 10, \"in_uid\" :  9, \"min_velocity\" : 15000, \"max_velocity\" : 20000, \"smooth\" : 1.02 },\n",
    " { \"name\" : \"multiply\",       \"uid\" : 11, \"in_uid\" :  8, \"gather_uids\" : [10] },\n",
    " { \"name\" : \"ifft\",           \"uid\" : 12, \"in_uid\" : 11, \"axis\" : 0},\n",
    " { \"name\" : \"ifft\",           \"uid\" : 13, \"in_uid\" : 12, \"axis\" : 1},\n",
    " { \"name\" : \"real\",           \"uid\" : 14, \"in_uid\" : 13},\n",
    " { \"name\" : \"butter\",         \"uid\" : 15, \"in_uid\" : 14, \"freq\" : 600, \"order\" : 5, \"type\" : \"highpass\"},\n",
    " { \"name\" : \"thumbnail\",      \"uid\" : 16, \"in_uid\" : 15, \"directory_out\" : \"filtered_png\", \"format\" : \"png\" },\n",
    " { \"name\" : \"multiply\",       \"uid\" : 17, \"in_uid\" : 15, \"gather_uids\" : [15] },\n",
    " { \"name\" : \"sta_lta\",        \"uid\" : 18, \"in_uid\" : 17, \"sta\" : 50, \"lta\" : 200},\n",
    " { \"name\" : \"thumbnail\",      \"uid\" : 19, \"in_uid\" : 18, \"directory_out\" : \"events_png\", \"format\" : \"png\" },\n",
    " { \"name\" : \"peak_to_peak\",   \"uid\" : 20, \"in_uid\" : 18, \"window_length\" : 200},\n",
    " { \"name\" : \"write_witsml\",   \"uid\" : 21, \"in_uid\" : 20, \"directory_out\" : \"p2p\", \"low_freq\" : [0], \"high_freq\" : [1],  \"gather_uids\" : [5], \"data_style\" : \"p2p\" }\n",
    "]\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Documenting flows for end-users\n",
    "Within **distpy** we make use of [GraphViz](https://graphviz.gitlab.io/_pages/pdf/dotguide.pdf) to rapidly picture the \n",
    "directed-graph structure of workflows.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    },
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"980pt\" viewBox=\"0.00 0.00 567.89 980.00\" width=\"568pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 976)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" points=\"-4,4 -4,-976 563.89,-976 563.89,4 -4,4\" stroke=\"none\"/>\n",
       "<!-- butter_1 -->\n",
       "<g class=\"node\" id=\"node1\"><title>butter_1</title>\n",
       "<ellipse cx=\"134.146\" cy=\"-882\" fill=\"none\" rx=\"31.6951\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"134.146\" y=\"-878.3\">butter</text>\n",
       "</g>\n",
       "<!-- butter_2 -->\n",
       "<g class=\"node\" id=\"node3\"><title>butter_2</title>\n",
       "<ellipse cx=\"46.1459\" cy=\"-810\" fill=\"none\" rx=\"31.6951\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"46.1459\" y=\"-806.3\">butter</text>\n",
       "</g>\n",
       "<!-- butter_1&#45;&gt;butter_2 -->\n",
       "<g class=\"edge\" id=\"edge2\"><title>butter_1-&gt;butter_2</title>\n",
       "<path d=\"M116.338,-866.834C103.575,-856.682 86.1897,-842.853 71.9146,-831.498\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"73.9324,-828.631 63.9275,-825.144 69.5747,-834.109 73.9324,-828.631\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- load_data_0 -->\n",
       "<g class=\"node\" id=\"node2\"><title>load_data_0</title>\n",
       "<ellipse cx=\"181.146\" cy=\"-954\" fill=\"none\" rx=\"55.7903\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"181.146\" y=\"-950.3\">load_data_0</text>\n",
       "</g>\n",
       "<!-- load_data_0&#45;&gt;butter_1 -->\n",
       "<g class=\"edge\" id=\"edge1\"><title>load_data_0-&gt;butter_1</title>\n",
       "<path d=\"M169.769,-936.055C164.086,-927.592 157.102,-917.19 150.827,-907.845\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"153.575,-905.658 145.095,-899.307 147.763,-909.56 153.575,-905.658\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- fft_4 -->\n",
       "<g class=\"node\" id=\"node5\"><title>fft_4</title>\n",
       "<ellipse cx=\"228.146\" cy=\"-882\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"228.146\" y=\"-878.3\">fft</text>\n",
       "</g>\n",
       "<!-- load_data_0&#45;&gt;fft_4 -->\n",
       "<g class=\"edge\" id=\"edge4\"><title>load_data_0-&gt;fft_4</title>\n",
       "<path d=\"M192.523,-936.055C198.347,-927.381 205.539,-916.669 211.933,-907.147\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"214.849,-909.083 217.518,-898.829 209.037,-905.181 214.849,-909.083\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- thumbnail_3 -->\n",
       "<g class=\"node\" id=\"node4\"><title>thumbnail_3</title>\n",
       "<ellipse cx=\"46.1459\" cy=\"-738\" fill=\"none\" rx=\"46.2923\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"46.1459\" y=\"-734.3\">thumbnail</text>\n",
       "</g>\n",
       "<!-- butter_2&#45;&gt;thumbnail_3 -->\n",
       "<g class=\"edge\" id=\"edge3\"><title>butter_2-&gt;thumbnail_3</title>\n",
       "<path d=\"M46.1459,-791.697C46.1459,-783.983 46.1459,-774.712 46.1459,-766.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"49.646,-766.104 46.1459,-756.104 42.646,-766.104 49.646,-766.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- rms_from_fft_5 -->\n",
       "<g class=\"node\" id=\"node6\"><title>rms_from_fft_5</title>\n",
       "<ellipse cx=\"298.146\" cy=\"-810\" fill=\"none\" rx=\"59.5901\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"298.146\" y=\"-806.3\">rms_from_fft</text>\n",
       "</g>\n",
       "<!-- fft_4&#45;&gt;rms_from_fft_5 -->\n",
       "<g class=\"edge\" id=\"edge5\"><title>fft_4-&gt;rms_from_fft_5</title>\n",
       "<path d=\"M242.65,-866.496C251.802,-857.344 263.84,-845.306 274.365,-834.781\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"277.102,-836.994 281.698,-827.448 272.152,-832.044 277.102,-836.994\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiple_calcs_6 -->\n",
       "<g class=\"node\" id=\"node7\"><title>multiple_calcs_6</title>\n",
       "<ellipse cx=\"158.146\" cy=\"-810\" fill=\"none\" rx=\"62.2891\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"158.146\" y=\"-806.3\">multiple_calcs</text>\n",
       "</g>\n",
       "<!-- fft_4&#45;&gt;multiple_calcs_6 -->\n",
       "<g class=\"edge\" id=\"edge6\"><title>fft_4-&gt;multiple_calcs_6</title>\n",
       "<path d=\"M213.642,-866.496C204.49,-857.344 192.452,-845.306 181.927,-834.781\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"184.14,-832.044 174.594,-827.448 179.19,-836.994 184.14,-832.044\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- fft_8 -->\n",
       "<g class=\"node\" id=\"node9\"><title>fft_8</title>\n",
       "<ellipse cx=\"403.146\" cy=\"-810\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"403.146\" y=\"-806.3\">fft</text>\n",
       "</g>\n",
       "<!-- fft_4&#45;&gt;fft_8 -->\n",
       "<g class=\"edge\" id=\"edge9\"><title>fft_4-&gt;fft_8</title>\n",
       "<path d=\"M251.482,-872.724C279.276,-862.725 326.991,-845.107 367.146,-828 368.958,-827.228 370.813,-826.417 372.679,-825.586\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"374.313,-828.687 381.948,-821.341 371.399,-822.322 374.313,-828.687\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- write_witsml_7 -->\n",
       "<g class=\"node\" id=\"node8\"><title>write_witsml_7</title>\n",
       "<ellipse cx=\"190.146\" cy=\"-738\" fill=\"none\" rx=\"56.59\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"190.146\" y=\"-734.3\">write_witsml</text>\n",
       "</g>\n",
       "<!-- rms_from_fft_5&#45;&gt;write_witsml_7 -->\n",
       "<g class=\"edge\" id=\"edge8\"><title>rms_from_fft_5-&gt;write_witsml_7</title>\n",
       "<path d=\"M274.177,-793.465C259.076,-783.677 239.381,-770.912 222.854,-760.2\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"224.343,-756.994 214.048,-754.492 220.536,-762.868 224.343,-756.994\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- write_witsml_21 -->\n",
       "<g class=\"node\" id=\"node22\"><title>write_witsml_21</title>\n",
       "<ellipse cx=\"398.146\" cy=\"-18\" fill=\"none\" rx=\"56.59\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"398.146\" y=\"-14.3\">write_witsml</text>\n",
       "</g>\n",
       "<!-- rms_from_fft_5&#45;&gt;write_witsml_21 -->\n",
       "<g class=\"edge\" id=\"edge25\"><title>rms_from_fft_5-&gt;write_witsml_21</title>\n",
       "<path d=\"M298.146,-791.951C298.146,-765.292 298.146,-712.115 298.146,-667 298.146,-667 298.146,-667 298.146,-161 298.146,-120.553 294.279,-105.363 317.146,-72 326.981,-57.6508 342.106,-46.2402 356.635,-37.7379\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"358.486,-40.7142 365.552,-32.8196 355.105,-34.5848 358.486,-40.7142\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiple_calcs_6&#45;&gt;write_witsml_7 -->\n",
       "<g class=\"edge\" id=\"edge7\"><title>multiple_calcs_6-&gt;write_witsml_7</title>\n",
       "<path d=\"M165.892,-792.055C169.533,-784.091 173.958,-774.411 178.027,-765.51\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"181.274,-766.825 182.249,-756.275 174.908,-763.915 181.274,-766.825\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- velocity_map_9 -->\n",
       "<g class=\"node\" id=\"node10\"><title>velocity_map_9</title>\n",
       "<ellipse cx=\"397.146\" cy=\"-738\" fill=\"none\" rx=\"59.5901\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"397.146\" y=\"-734.3\">velocity_map</text>\n",
       "</g>\n",
       "<!-- fft_8&#45;&gt;velocity_map_9 -->\n",
       "<g class=\"edge\" id=\"edge10\"><title>fft_8-&gt;velocity_map_9</title>\n",
       "<path d=\"M401.663,-791.697C401.002,-783.983 400.207,-774.712 399.47,-766.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"402.953,-765.769 398.612,-756.104 395.979,-766.367 402.953,-765.769\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiply_11 -->\n",
       "<g class=\"node\" id=\"node12\"><title>multiply_11</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-594\" fill=\"none\" rx=\"39.7935\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-590.3\">multiply</text>\n",
       "</g>\n",
       "<!-- fft_8&#45;&gt;multiply_11 -->\n",
       "<g class=\"edge\" id=\"edge12\"><title>fft_8-&gt;multiply_11</title>\n",
       "<path d=\"M423.29,-797.914C437.862,-788.726 456.602,-774.236 466.146,-756 488.462,-713.358 487.615,-655.621 484.621,-622.133\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"488.101,-621.754 483.601,-612.163 481.137,-622.467 488.101,-621.754\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- velocity_mask_10 -->\n",
       "<g class=\"node\" id=\"node11\"><title>velocity_mask_10</title>\n",
       "<ellipse cx=\"396.146\" cy=\"-666\" fill=\"none\" rx=\"63.0888\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"396.146\" y=\"-662.3\">velocity_mask</text>\n",
       "</g>\n",
       "<!-- velocity_map_9&#45;&gt;velocity_mask_10 -->\n",
       "<g class=\"edge\" id=\"edge11\"><title>velocity_map_9-&gt;velocity_mask_10</title>\n",
       "<path d=\"M396.899,-719.697C396.789,-711.983 396.656,-702.712 396.533,-694.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"400.033,-694.053 396.39,-684.104 393.034,-694.153 400.033,-694.053\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- velocity_mask_10&#45;&gt;multiply_11 -->\n",
       "<g class=\"edge\" id=\"edge13\"><title>velocity_mask_10-&gt;multiply_11</title>\n",
       "<path d=\"M415.86,-648.765C427.447,-639.223 442.241,-627.04 454.815,-616.684\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"457.208,-619.248 462.702,-610.189 452.758,-613.844 457.208,-619.248\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- ifft_12 -->\n",
       "<g class=\"node\" id=\"node13\"><title>ifft_12</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-522\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-518.3\">ifft</text>\n",
       "</g>\n",
       "<!-- multiply_11&#45;&gt;ifft_12 -->\n",
       "<g class=\"edge\" id=\"edge14\"><title>multiply_11-&gt;ifft_12</title>\n",
       "<path d=\"M481.146,-575.697C481.146,-567.983 481.146,-558.712 481.146,-550.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"484.646,-550.104 481.146,-540.104 477.646,-550.104 484.646,-550.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- ifft_13 -->\n",
       "<g class=\"node\" id=\"node14\"><title>ifft_13</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-450\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-446.3\">ifft</text>\n",
       "</g>\n",
       "<!-- ifft_12&#45;&gt;ifft_13 -->\n",
       "<g class=\"edge\" id=\"edge15\"><title>ifft_12-&gt;ifft_13</title>\n",
       "<path d=\"M481.146,-503.697C481.146,-495.983 481.146,-486.712 481.146,-478.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"484.646,-478.104 481.146,-468.104 477.646,-478.104 484.646,-478.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- real_14 -->\n",
       "<g class=\"node\" id=\"node15\"><title>real_14</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-378\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-374.3\">real</text>\n",
       "</g>\n",
       "<!-- ifft_13&#45;&gt;real_14 -->\n",
       "<g class=\"edge\" id=\"edge16\"><title>ifft_13-&gt;real_14</title>\n",
       "<path d=\"M481.146,-431.697C481.146,-423.983 481.146,-414.712 481.146,-406.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"484.646,-406.104 481.146,-396.104 477.646,-406.104 484.646,-406.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- butter_15 -->\n",
       "<g class=\"node\" id=\"node16\"><title>butter_15</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-306\" fill=\"none\" rx=\"31.6951\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-302.3\">butter</text>\n",
       "</g>\n",
       "<!-- real_14&#45;&gt;butter_15 -->\n",
       "<g class=\"edge\" id=\"edge17\"><title>real_14-&gt;butter_15</title>\n",
       "<path d=\"M481.146,-359.697C481.146,-351.983 481.146,-342.712 481.146,-334.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"484.646,-334.104 481.146,-324.104 477.646,-334.104 484.646,-334.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- thumbnail_16 -->\n",
       "<g class=\"node\" id=\"node17\"><title>thumbnail_16</title>\n",
       "<ellipse cx=\"377.146\" cy=\"-234\" fill=\"none\" rx=\"46.2923\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"377.146\" y=\"-230.3\">thumbnail</text>\n",
       "</g>\n",
       "<!-- butter_15&#45;&gt;thumbnail_16 -->\n",
       "<g class=\"edge\" id=\"edge18\"><title>butter_15-&gt;thumbnail_16</title>\n",
       "<path d=\"M461.094,-291.503C446.014,-281.354 425.083,-267.265 407.894,-255.696\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"409.547,-252.59 399.297,-249.909 405.639,-258.397 409.547,-252.59\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiply_17 -->\n",
       "<g class=\"node\" id=\"node18\"><title>multiply_17</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-234\" fill=\"none\" rx=\"39.7935\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-230.3\">multiply</text>\n",
       "</g>\n",
       "<!-- butter_15&#45;&gt;multiply_17 -->\n",
       "<g class=\"edge\" id=\"edge19\"><title>butter_15-&gt;multiply_17</title>\n",
       "<path d=\"M475.268,-288.055C474.45,-280.346 474.207,-271.027 474.541,-262.364\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"478.04,-262.491 475.233,-252.275 471.057,-262.012 478.04,-262.491\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- butter_15&#45;&gt;multiply_17 -->\n",
       "<g class=\"edge\" id=\"edge20\"><title>butter_15-&gt;multiply_17</title>\n",
       "<path d=\"M487.024,-288.055C487.842,-280.346 488.085,-271.027 487.751,-262.364\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"491.235,-262.012 487.059,-252.275 484.252,-262.491 491.235,-262.012\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- sta_lta_18 -->\n",
       "<g class=\"node\" id=\"node19\"><title>sta_lta_18</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-162\" fill=\"none\" rx=\"34.394\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-158.3\">sta_lta</text>\n",
       "</g>\n",
       "<!-- multiply_17&#45;&gt;sta_lta_18 -->\n",
       "<g class=\"edge\" id=\"edge21\"><title>multiply_17-&gt;sta_lta_18</title>\n",
       "<path d=\"M481.146,-215.697C481.146,-207.983 481.146,-198.712 481.146,-190.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"484.646,-190.104 481.146,-180.104 477.646,-190.104 484.646,-190.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- thumbnail_19 -->\n",
       "<g class=\"node\" id=\"node20\"><title>thumbnail_19</title>\n",
       "<ellipse cx=\"372.146\" cy=\"-90\" fill=\"none\" rx=\"46.2923\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"372.146\" y=\"-86.3\">thumbnail</text>\n",
       "</g>\n",
       "<!-- sta_lta_18&#45;&gt;thumbnail_19 -->\n",
       "<g class=\"edge\" id=\"edge22\"><title>sta_lta_18-&gt;thumbnail_19</title>\n",
       "<path d=\"M460.13,-147.503C444.074,-137.192 421.689,-122.816 403.516,-111.146\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"405.285,-108.122 394.979,-105.664 401.502,-114.012 405.285,-108.122\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- peak_to_peak_20 -->\n",
       "<g class=\"node\" id=\"node21\"><title>peak_to_peak_20</title>\n",
       "<ellipse cx=\"498.146\" cy=\"-90\" fill=\"none\" rx=\"61.99\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"498.146\" y=\"-86.3\">peak_to_peak</text>\n",
       "</g>\n",
       "<!-- sta_lta_18&#45;&gt;peak_to_peak_20 -->\n",
       "<g class=\"edge\" id=\"edge23\"><title>sta_lta_18-&gt;peak_to_peak_20</title>\n",
       "<path d=\"M485.261,-144.055C487.154,-136.261 489.446,-126.822 491.57,-118.079\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"494.992,-118.819 493.95,-108.275 488.189,-117.167 494.992,-118.819\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- peak_to_peak_20&#45;&gt;write_witsml_21 -->\n",
       "<g class=\"edge\" id=\"edge24\"><title>peak_to_peak_20-&gt;write_witsml_21</title>\n",
       "<path d=\"M475.454,-73.1159C461.677,-63.472 443.91,-51.035 428.883,-40.5162\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"430.603,-37.4474 420.403,-34.5801 426.588,-43.1821 430.603,-37.4474\" stroke=\"black\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import SVG, Latex, Markdown\n",
    "from graphviz import Source\n",
    "from ipywidgets import interactive\n",
    "from IPython.display import display\n",
    "import copy\n",
    "\n",
    "import distpy.io_help.io_helpers as io_helpers\n",
    "import distpy.workers.strainrate2summary\n",
    "\n",
    "# Feed the command list into the dot_graph function\n",
    "dotgraph = io_helpers.dot_graph(myFlow['command_list'])\n",
    "\n",
    "# display the results as a Scalable Vector Graphic\n",
    "graph = Source(' '.join(dotgraph))\n",
    "display(SVG(graph.pipe(format='svg')))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To enhance the presentation for the end-user, we use the optional `comment` and `formatting` fields on the commands. \n",
    "For example to highlight the noise logging path we could use the following code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "## Highlighting the Noise Logging path"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "We highlight the noise logging path by setting the comment and formatting fields in the noise logging commands."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "The section of interest is highlighted in green and yellow."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"980pt\" viewBox=\"0.00 0.00 684.89 980.00\" width=\"685pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 976)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" points=\"-4,4 -4,-976 680.89,-976 680.89,4 -4,4\" stroke=\"none\"/>\n",
       "<!-- butter_1 -->\n",
       "<g class=\"node\" id=\"node1\"><title>butter_1</title>\n",
       "<ellipse cx=\"177.146\" cy=\"-882\" fill=\"none\" rx=\"31.6951\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"177.146\" y=\"-878.3\">butter</text>\n",
       "</g>\n",
       "<!-- butter_2 -->\n",
       "<g class=\"node\" id=\"node3\"><title>butter_2</title>\n",
       "<ellipse cx=\"46.1459\" cy=\"-810\" fill=\"none\" rx=\"31.6951\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"46.1459\" y=\"-806.3\">butter</text>\n",
       "</g>\n",
       "<!-- butter_1&#45;&gt;butter_2 -->\n",
       "<g class=\"edge\" id=\"edge2\"><title>butter_1-&gt;butter_2</title>\n",
       "<path d=\"M154.626,-868.967C133.444,-857.648 101.523,-840.591 77.7862,-827.907\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"79.2795,-824.737 68.8101,-823.111 75.9804,-830.911 79.2795,-824.737\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- load_data_0 -->\n",
       "<g class=\"node\" id=\"node2\"><title>load_data_0</title>\n",
       "<ellipse cx=\"243.146\" cy=\"-954\" fill=\"none\" rx=\"55.7903\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"243.146\" y=\"-950.3\">load_data_0</text>\n",
       "</g>\n",
       "<!-- load_data_0&#45;&gt;butter_1 -->\n",
       "<g class=\"edge\" id=\"edge1\"><title>load_data_0-&gt;butter_1</title>\n",
       "<path d=\"M227.505,-936.411C218.963,-927.351 208.251,-915.99 198.905,-906.078\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"201.177,-903.386 191.77,-898.511 196.084,-908.188 201.177,-903.386\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- fft_4 -->\n",
       "<g class=\"node\" id=\"node5\"><title>fft_4</title>\n",
       "<ellipse cx=\"310.146\" cy=\"-882\" fill=\"green\" rx=\"58.4896\" ry=\"18\" stroke=\"green\"/>\n",
       "<text fill=\"yellow\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"310.146\" y=\"-878.3\">x-f transform</text>\n",
       "</g>\n",
       "<!-- load_data_0&#45;&gt;fft_4 -->\n",
       "<g class=\"edge\" id=\"edge4\"><title>load_data_0-&gt;fft_4</title>\n",
       "<path d=\"M259.024,-936.411C267.451,-927.606 277.959,-916.628 287.252,-906.919\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"289.996,-909.114 294.382,-899.47 284.939,-904.274 289.996,-909.114\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- thumbnail_3 -->\n",
       "<g class=\"node\" id=\"node4\"><title>thumbnail_3</title>\n",
       "<ellipse cx=\"46.1459\" cy=\"-738\" fill=\"none\" rx=\"46.2923\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"46.1459\" y=\"-734.3\">thumbnail</text>\n",
       "</g>\n",
       "<!-- butter_2&#45;&gt;thumbnail_3 -->\n",
       "<g class=\"edge\" id=\"edge3\"><title>butter_2-&gt;thumbnail_3</title>\n",
       "<path d=\"M46.1459,-791.697C46.1459,-783.983 46.1459,-774.712 46.1459,-766.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"49.646,-766.104 46.1459,-756.104 42.646,-766.104 49.646,-766.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- rms_from_fft_5 -->\n",
       "<g class=\"node\" id=\"node6\"><title>rms_from_fft_5</title>\n",
       "<ellipse cx=\"415.146\" cy=\"-810\" fill=\"green\" rx=\"83.3857\" ry=\"18\" stroke=\"green\"/>\n",
       "<text fill=\"yellow\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"415.146\" y=\"-806.3\">Compute BAND-00</text>\n",
       "</g>\n",
       "<!-- fft_4&#45;&gt;rms_from_fft_5 -->\n",
       "<g class=\"edge\" id=\"edge5\"><title>fft_4-&gt;rms_from_fft_5</title>\n",
       "<path d=\"M333.449,-865.465C347.824,-855.881 366.483,-843.442 382.338,-832.872\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"384.434,-835.681 390.814,-827.222 380.552,-829.856 384.434,-835.681\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiple_calcs_6 -->\n",
       "<g class=\"node\" id=\"node7\"><title>multiple_calcs_6</title>\n",
       "<ellipse cx=\"205.146\" cy=\"-810\" fill=\"green\" rx=\"109.381\" ry=\"18\" stroke=\"green\"/>\n",
       "<text fill=\"yellow\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"205.146\" y=\"-806.3\">Copmute Noise Log bands</text>\n",
       "</g>\n",
       "<!-- fft_4&#45;&gt;multiple_calcs_6 -->\n",
       "<g class=\"edge\" id=\"edge6\"><title>fft_4-&gt;multiple_calcs_6</title>\n",
       "<path d=\"M286.843,-865.465C272.671,-856.017 254.338,-843.795 238.63,-833.323\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"240.479,-830.349 230.217,-827.714 236.596,-836.173 240.479,-830.349\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- fft_8 -->\n",
       "<g class=\"node\" id=\"node9\"><title>fft_8</title>\n",
       "<ellipse cx=\"543.146\" cy=\"-810\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"543.146\" y=\"-806.3\">fft</text>\n",
       "</g>\n",
       "<!-- fft_4&#45;&gt;fft_8 -->\n",
       "<g class=\"edge\" id=\"edge9\"><title>fft_4-&gt;fft_8</title>\n",
       "<path d=\"M356.646,-870.964C397.031,-861.665 456.778,-846.5 507.146,-828 508.995,-827.321 510.879,-826.582 512.766,-825.806\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"514.346,-828.935 522.094,-821.709 511.531,-822.526 514.346,-828.935\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- write_witsml_7 -->\n",
       "<g class=\"node\" id=\"node8\"><title>write_witsml_7</title>\n",
       "<ellipse cx=\"254.146\" cy=\"-738\" fill=\"green\" rx=\"83.6854\" ry=\"18\" stroke=\"green\"/>\n",
       "<text fill=\"yellow\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"254.146\" y=\"-734.3\">Export to WITSML</text>\n",
       "</g>\n",
       "<!-- rms_from_fft_5&#45;&gt;write_witsml_7 -->\n",
       "<g class=\"edge\" id=\"edge8\"><title>rms_from_fft_5-&gt;write_witsml_7</title>\n",
       "<path d=\"M379.814,-793.638C356.093,-783.325 324.636,-769.648 299.129,-758.558\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"300.24,-755.224 289.673,-754.447 297.449,-761.644 300.24,-755.224\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- write_witsml_21 -->\n",
       "<g class=\"node\" id=\"node22\"><title>write_witsml_21</title>\n",
       "<ellipse cx=\"515.146\" cy=\"-18\" fill=\"none\" rx=\"56.59\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"515.146\" y=\"-14.3\">write_witsml</text>\n",
       "</g>\n",
       "<!-- rms_from_fft_5&#45;&gt;write_witsml_21 -->\n",
       "<g class=\"edge\" id=\"edge25\"><title>rms_from_fft_5-&gt;write_witsml_21</title>\n",
       "<path d=\"M415.146,-791.951C415.146,-765.292 415.146,-712.115 415.146,-667 415.146,-667 415.146,-667 415.146,-161 415.146,-120.553 411.279,-105.363 434.146,-72 443.981,-57.6508 459.106,-46.2402 473.635,-37.7379\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"475.486,-40.7142 482.552,-32.8196 472.105,-34.5848 475.486,-40.7142\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiple_calcs_6&#45;&gt;write_witsml_7 -->\n",
       "<g class=\"edge\" id=\"edge7\"><title>multiple_calcs_6-&gt;write_witsml_7</title>\n",
       "<path d=\"M217.007,-792.055C222.76,-783.837 229.792,-773.791 236.184,-764.66\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"239.186,-766.475 242.053,-756.275 233.451,-762.461 239.186,-766.475\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- velocity_map_9 -->\n",
       "<g class=\"node\" id=\"node10\"><title>velocity_map_9</title>\n",
       "<ellipse cx=\"525.146\" cy=\"-738\" fill=\"none\" rx=\"59.5901\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"525.146\" y=\"-734.3\">velocity_map</text>\n",
       "</g>\n",
       "<!-- fft_8&#45;&gt;velocity_map_9 -->\n",
       "<g class=\"edge\" id=\"edge10\"><title>fft_8-&gt;velocity_map_9</title>\n",
       "<path d=\"M538.789,-792.055C536.784,-784.261 534.357,-774.822 532.109,-766.079\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"535.468,-765.089 529.588,-756.275 528.689,-766.832 535.468,-765.089\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiply_11 -->\n",
       "<g class=\"node\" id=\"node12\"><title>multiply_11</title>\n",
       "<ellipse cx=\"604.146\" cy=\"-594\" fill=\"none\" rx=\"39.7935\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"604.146\" y=\"-590.3\">multiply</text>\n",
       "</g>\n",
       "<!-- fft_8&#45;&gt;multiply_11 -->\n",
       "<g class=\"edge\" id=\"edge12\"><title>fft_8-&gt;multiply_11</title>\n",
       "<path d=\"M560.892,-796.09C572.582,-786.478 587.004,-772.249 594.146,-756 613.28,-712.465 611.431,-655.849 608.016,-622.659\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"611.45,-621.887 606.826,-612.354 604.496,-622.69 611.45,-621.887\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- velocity_mask_10 -->\n",
       "<g class=\"node\" id=\"node11\"><title>velocity_mask_10</title>\n",
       "<ellipse cx=\"524.146\" cy=\"-666\" fill=\"none\" rx=\"63.0888\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"524.146\" y=\"-662.3\">velocity_mask</text>\n",
       "</g>\n",
       "<!-- velocity_map_9&#45;&gt;velocity_mask_10 -->\n",
       "<g class=\"edge\" id=\"edge11\"><title>velocity_map_9-&gt;velocity_mask_10</title>\n",
       "<path d=\"M524.899,-719.697C524.789,-711.983 524.656,-702.712 524.533,-694.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"528.033,-694.053 524.39,-684.104 521.034,-694.153 528.033,-694.053\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- velocity_mask_10&#45;&gt;multiply_11 -->\n",
       "<g class=\"edge\" id=\"edge13\"><title>velocity_mask_10-&gt;multiply_11</title>\n",
       "<path d=\"M542.701,-648.765C553.502,-639.314 567.264,-627.271 579.025,-616.98\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"581.566,-619.408 586.787,-610.189 576.957,-614.14 581.566,-619.408\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- ifft_12 -->\n",
       "<g class=\"node\" id=\"node13\"><title>ifft_12</title>\n",
       "<ellipse cx=\"604.146\" cy=\"-522\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"604.146\" y=\"-518.3\">ifft</text>\n",
       "</g>\n",
       "<!-- multiply_11&#45;&gt;ifft_12 -->\n",
       "<g class=\"edge\" id=\"edge14\"><title>multiply_11-&gt;ifft_12</title>\n",
       "<path d=\"M604.146,-575.697C604.146,-567.983 604.146,-558.712 604.146,-550.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"607.646,-550.104 604.146,-540.104 600.646,-550.104 607.646,-550.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- ifft_13 -->\n",
       "<g class=\"node\" id=\"node14\"><title>ifft_13</title>\n",
       "<ellipse cx=\"604.146\" cy=\"-450\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"604.146\" y=\"-446.3\">ifft</text>\n",
       "</g>\n",
       "<!-- ifft_12&#45;&gt;ifft_13 -->\n",
       "<g class=\"edge\" id=\"edge15\"><title>ifft_12-&gt;ifft_13</title>\n",
       "<path d=\"M604.146,-503.697C604.146,-495.983 604.146,-486.712 604.146,-478.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"607.646,-478.104 604.146,-468.104 600.646,-478.104 607.646,-478.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- real_14 -->\n",
       "<g class=\"node\" id=\"node15\"><title>real_14</title>\n",
       "<ellipse cx=\"604.146\" cy=\"-378\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"604.146\" y=\"-374.3\">real</text>\n",
       "</g>\n",
       "<!-- ifft_13&#45;&gt;real_14 -->\n",
       "<g class=\"edge\" id=\"edge16\"><title>ifft_13-&gt;real_14</title>\n",
       "<path d=\"M604.146,-431.697C604.146,-423.983 604.146,-414.712 604.146,-406.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"607.646,-406.104 604.146,-396.104 600.646,-406.104 607.646,-406.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- butter_15 -->\n",
       "<g class=\"node\" id=\"node16\"><title>butter_15</title>\n",
       "<ellipse cx=\"604.146\" cy=\"-306\" fill=\"none\" rx=\"31.6951\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"604.146\" y=\"-302.3\">butter</text>\n",
       "</g>\n",
       "<!-- real_14&#45;&gt;butter_15 -->\n",
       "<g class=\"edge\" id=\"edge17\"><title>real_14-&gt;butter_15</title>\n",
       "<path d=\"M604.146,-359.697C604.146,-351.983 604.146,-342.712 604.146,-334.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"607.646,-334.104 604.146,-324.104 600.646,-334.104 607.646,-334.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- thumbnail_16 -->\n",
       "<g class=\"node\" id=\"node17\"><title>thumbnail_16</title>\n",
       "<ellipse cx=\"500.146\" cy=\"-234\" fill=\"none\" rx=\"46.2923\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"500.146\" y=\"-230.3\">thumbnail</text>\n",
       "</g>\n",
       "<!-- butter_15&#45;&gt;thumbnail_16 -->\n",
       "<g class=\"edge\" id=\"edge18\"><title>butter_15-&gt;thumbnail_16</title>\n",
       "<path d=\"M584.094,-291.503C569.014,-281.354 548.083,-267.265 530.894,-255.696\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"532.547,-252.59 522.297,-249.909 528.639,-258.397 532.547,-252.59\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiply_17 -->\n",
       "<g class=\"node\" id=\"node18\"><title>multiply_17</title>\n",
       "<ellipse cx=\"604.146\" cy=\"-234\" fill=\"none\" rx=\"39.7935\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"604.146\" y=\"-230.3\">multiply</text>\n",
       "</g>\n",
       "<!-- butter_15&#45;&gt;multiply_17 -->\n",
       "<g class=\"edge\" id=\"edge19\"><title>butter_15-&gt;multiply_17</title>\n",
       "<path d=\"M598.268,-288.055C597.45,-280.346 597.207,-271.027 597.541,-262.364\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"601.04,-262.491 598.233,-252.275 594.057,-262.012 601.04,-262.491\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- butter_15&#45;&gt;multiply_17 -->\n",
       "<g class=\"edge\" id=\"edge20\"><title>butter_15-&gt;multiply_17</title>\n",
       "<path d=\"M610.024,-288.055C610.842,-280.346 611.085,-271.027 610.751,-262.364\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"614.235,-262.012 610.059,-252.275 607.252,-262.491 614.235,-262.012\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- sta_lta_18 -->\n",
       "<g class=\"node\" id=\"node19\"><title>sta_lta_18</title>\n",
       "<ellipse cx=\"604.146\" cy=\"-162\" fill=\"none\" rx=\"34.394\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"604.146\" y=\"-158.3\">sta_lta</text>\n",
       "</g>\n",
       "<!-- multiply_17&#45;&gt;sta_lta_18 -->\n",
       "<g class=\"edge\" id=\"edge21\"><title>multiply_17-&gt;sta_lta_18</title>\n",
       "<path d=\"M604.146,-215.697C604.146,-207.983 604.146,-198.712 604.146,-190.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"607.646,-190.104 604.146,-180.104 600.646,-190.104 607.646,-190.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- thumbnail_19 -->\n",
       "<g class=\"node\" id=\"node20\"><title>thumbnail_19</title>\n",
       "<ellipse cx=\"489.146\" cy=\"-90\" fill=\"none\" rx=\"46.2923\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"489.146\" y=\"-86.3\">thumbnail</text>\n",
       "</g>\n",
       "<!-- sta_lta_18&#45;&gt;thumbnail_19 -->\n",
       "<g class=\"edge\" id=\"edge22\"><title>sta_lta_18-&gt;thumbnail_19</title>\n",
       "<path d=\"M582.515,-147.834C565.363,-137.393 541.12,-122.636 521.636,-110.777\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"523.423,-107.767 513.061,-105.557 519.783,-113.746 523.423,-107.767\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- peak_to_peak_20 -->\n",
       "<g class=\"node\" id=\"node21\"><title>peak_to_peak_20</title>\n",
       "<ellipse cx=\"615.146\" cy=\"-90\" fill=\"none\" rx=\"61.99\" ry=\"18\" stroke=\"black\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"615.146\" y=\"-86.3\">peak_to_peak</text>\n",
       "</g>\n",
       "<!-- sta_lta_18&#45;&gt;peak_to_peak_20 -->\n",
       "<g class=\"edge\" id=\"edge23\"><title>sta_lta_18-&gt;peak_to_peak_20</title>\n",
       "<path d=\"M606.865,-143.697C608.077,-135.983 609.534,-126.712 610.885,-118.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"614.363,-118.526 612.458,-108.104 607.448,-117.44 614.363,-118.526\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- peak_to_peak_20&#45;&gt;write_witsml_21 -->\n",
       "<g class=\"edge\" id=\"edge24\"><title>peak_to_peak_20-&gt;write_witsml_21</title>\n",
       "<path d=\"M592.454,-73.1159C578.677,-63.472 560.91,-51.035 545.883,-40.5162\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"547.603,-37.4474 537.403,-34.5801 543.588,-43.1821 547.603,-37.4474\" stroke=\"black\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import SVG, Latex, Markdown\n",
    "from graphviz import Source\n",
    "from ipywidgets import interactive\n",
    "from IPython.display import display\n",
    "import copy\n",
    "\n",
    "import distpy.io_help.io_helpers as io_helpers\n",
    "import distpy.workers.strainrate2summary\n",
    "\n",
    "\n",
    "lines=[]\n",
    "lines.append('## Highlighting the Noise Logging path')\n",
    "lines.append('We highlight the noise logging path by setting the comment and formatting fields in the noise logging commands.')\n",
    "lines.append('The section of interest is highlighted in green and yellow.')\n",
    "\n",
    "formatting = \"color=green,style=filled,fontcolor=yellow\"\n",
    "myFlow['command_list'][3]['comment']='x-f transform'\n",
    "myFlow['command_list'][4]['comment']='Compute BAND-00'\n",
    "myFlow['command_list'][5]['comment']='Copmute Noise Log bands'\n",
    "myFlow['command_list'][6]['comment']='Export to WITSML'\n",
    "for a in range(3,7):\n",
    "    myFlow['command_list'][a]['formatting'] = formatting\n",
    "\n",
    "\n",
    "# Feed the command list into the dot_graph function\n",
    "dotgraph = io_helpers.dot_graph(myFlow['command_list'])\n",
    "\n",
    "\n",
    "# Display the text\n",
    "for line in lines:\n",
    "    display(Markdown(line))\n",
    "\n",
    "# display the results as a Scalable Vector Graphic\n",
    "graph = Source(' '.join(dotgraph))\n",
    "display(SVG(graph.pipe(format='svg')))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Documenting flows for the deployment team\n",
    "Whilst it is very useful to freely comment and colour workflows for end-users, the deployment team are usually more interested\n",
    "in details - what functions are used and which are GPU-compatible.\n",
    "\n",
    "**distpy** allows the generation of a null command structure, which mimics the objects created at run-time. Feeding this into the `dot_graph`\n",
    "function returns a view of the flow with the key details."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"980pt\" viewBox=\"0.00 0.00 567.89 980.00\" width=\"568pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 976)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" points=\"-4,4 -4,-976 563.89,-976 563.89,4 -4,4\" stroke=\"none\"/>\n",
       "<!-- load_data_0 -->\n",
       "<g class=\"node\" id=\"node1\"><title>load_data_0</title>\n",
       "<ellipse cx=\"181.146\" cy=\"-954\" fill=\"red\" rx=\"46.2923\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"181.146\" y=\"-950.3\">load_data</text>\n",
       "</g>\n",
       "<!-- butter_1 -->\n",
       "<g class=\"node\" id=\"node2\"><title>butter_1</title>\n",
       "<ellipse cx=\"134.146\" cy=\"-882\" fill=\"red\" rx=\"31.6951\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"134.146\" y=\"-878.3\">butter</text>\n",
       "</g>\n",
       "<!-- load_data_0&#45;&gt;butter_1 -->\n",
       "<g class=\"edge\" id=\"edge1\"><title>load_data_0-&gt;butter_1</title>\n",
       "<path d=\"M170.008,-936.411C164.188,-927.744 156.955,-916.971 150.512,-907.375\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"153.361,-905.339 144.881,-898.988 147.549,-909.241 153.361,-905.339\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- fft_4 -->\n",
       "<g class=\"node\" id=\"node5\"><title>fft_4</title>\n",
       "<ellipse cx=\"228.146\" cy=\"-882\" fill=\"green\" rx=\"27\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"228.146\" y=\"-878.3\">fft</text>\n",
       "</g>\n",
       "<!-- load_data_0&#45;&gt;fft_4 -->\n",
       "<g class=\"edge\" id=\"edge4\"><title>load_data_0-&gt;fft_4</title>\n",
       "<path d=\"M192.284,-936.411C198.104,-927.744 205.337,-916.971 211.78,-907.375\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"214.742,-909.241 217.411,-898.988 208.931,-905.339 214.742,-909.241\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- butter_2 -->\n",
       "<g class=\"node\" id=\"node3\"><title>butter_2</title>\n",
       "<ellipse cx=\"46.1459\" cy=\"-810\" fill=\"red\" rx=\"31.6951\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"46.1459\" y=\"-806.3\">butter</text>\n",
       "</g>\n",
       "<!-- butter_1&#45;&gt;butter_2 -->\n",
       "<g class=\"edge\" id=\"edge2\"><title>butter_1-&gt;butter_2</title>\n",
       "<path d=\"M116.338,-866.834C103.575,-856.682 86.1897,-842.853 71.9146,-831.498\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"73.9324,-828.631 63.9275,-825.144 69.5747,-834.109 73.9324,-828.631\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- thumbnail_3 -->\n",
       "<g class=\"node\" id=\"node4\"><title>thumbnail_3</title>\n",
       "<ellipse cx=\"46.1459\" cy=\"-738\" fill=\"red\" rx=\"46.2923\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"46.1459\" y=\"-734.3\">thumbnail</text>\n",
       "</g>\n",
       "<!-- butter_2&#45;&gt;thumbnail_3 -->\n",
       "<g class=\"edge\" id=\"edge3\"><title>butter_2-&gt;thumbnail_3</title>\n",
       "<path d=\"M46.1459,-791.697C46.1459,-783.983 46.1459,-774.712 46.1459,-766.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"49.646,-766.104 46.1459,-756.104 42.646,-766.104 49.646,-766.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- rms_from_fft_5 -->\n",
       "<g class=\"node\" id=\"node6\"><title>rms_from_fft_5</title>\n",
       "<ellipse cx=\"298.146\" cy=\"-810\" fill=\"green\" rx=\"59.5901\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"298.146\" y=\"-806.3\">rms_from_fft</text>\n",
       "</g>\n",
       "<!-- fft_4&#45;&gt;rms_from_fft_5 -->\n",
       "<g class=\"edge\" id=\"edge5\"><title>fft_4-&gt;rms_from_fft_5</title>\n",
       "<path d=\"M242.65,-866.496C251.802,-857.344 263.84,-845.306 274.365,-834.781\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"277.102,-836.994 281.698,-827.448 272.152,-832.044 277.102,-836.994\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiple_calcs_6 -->\n",
       "<g class=\"node\" id=\"node7\"><title>multiple_calcs_6</title>\n",
       "<ellipse cx=\"158.146\" cy=\"-810\" fill=\"green\" rx=\"62.2891\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"158.146\" y=\"-806.3\">multiple_calcs</text>\n",
       "</g>\n",
       "<!-- fft_4&#45;&gt;multiple_calcs_6 -->\n",
       "<g class=\"edge\" id=\"edge6\"><title>fft_4-&gt;multiple_calcs_6</title>\n",
       "<path d=\"M213.642,-866.496C204.49,-857.344 192.452,-845.306 181.927,-834.781\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"184.14,-832.044 174.594,-827.448 179.19,-836.994 184.14,-832.044\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- fft_8 -->\n",
       "<g class=\"node\" id=\"node9\"><title>fft_8</title>\n",
       "<ellipse cx=\"403.146\" cy=\"-810\" fill=\"green\" rx=\"27\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"403.146\" y=\"-806.3\">fft</text>\n",
       "</g>\n",
       "<!-- fft_4&#45;&gt;fft_8 -->\n",
       "<g class=\"edge\" id=\"edge9\"><title>fft_4-&gt;fft_8</title>\n",
       "<path d=\"M251.482,-872.724C279.276,-862.725 326.991,-845.107 367.146,-828 368.958,-827.228 370.813,-826.417 372.679,-825.586\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"374.313,-828.687 381.948,-821.341 371.399,-822.322 374.313,-828.687\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- write_witsml_7 -->\n",
       "<g class=\"node\" id=\"node8\"><title>write_witsml_7</title>\n",
       "<ellipse cx=\"190.146\" cy=\"-738\" fill=\"red\" rx=\"56.59\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"190.146\" y=\"-734.3\">write_witsml</text>\n",
       "</g>\n",
       "<!-- rms_from_fft_5&#45;&gt;write_witsml_7 -->\n",
       "<g class=\"edge\" id=\"edge8\"><title>rms_from_fft_5-&gt;write_witsml_7</title>\n",
       "<path d=\"M274.177,-793.465C259.076,-783.677 239.381,-770.912 222.854,-760.2\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"224.343,-756.994 214.048,-754.492 220.536,-762.868 224.343,-756.994\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- write_witsml_21 -->\n",
       "<g class=\"node\" id=\"node22\"><title>write_witsml_21</title>\n",
       "<ellipse cx=\"398.146\" cy=\"-18\" fill=\"red\" rx=\"56.59\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"398.146\" y=\"-14.3\">write_witsml</text>\n",
       "</g>\n",
       "<!-- rms_from_fft_5&#45;&gt;write_witsml_21 -->\n",
       "<g class=\"edge\" id=\"edge25\"><title>rms_from_fft_5-&gt;write_witsml_21</title>\n",
       "<path d=\"M298.146,-791.951C298.146,-765.292 298.146,-712.115 298.146,-667 298.146,-667 298.146,-667 298.146,-161 298.146,-120.553 294.279,-105.363 317.146,-72 326.981,-57.6508 342.106,-46.2402 356.635,-37.7379\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"358.486,-40.7142 365.552,-32.8196 355.105,-34.5848 358.486,-40.7142\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiple_calcs_6&#45;&gt;write_witsml_7 -->\n",
       "<g class=\"edge\" id=\"edge7\"><title>multiple_calcs_6-&gt;write_witsml_7</title>\n",
       "<path d=\"M165.892,-792.055C169.533,-784.091 173.958,-774.411 178.027,-765.51\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"181.274,-766.825 182.249,-756.275 174.908,-763.915 181.274,-766.825\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- velocity_map_9 -->\n",
       "<g class=\"node\" id=\"node10\"><title>velocity_map_9</title>\n",
       "<ellipse cx=\"397.146\" cy=\"-738\" fill=\"red\" rx=\"59.5901\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"397.146\" y=\"-734.3\">velocity_map</text>\n",
       "</g>\n",
       "<!-- fft_8&#45;&gt;velocity_map_9 -->\n",
       "<g class=\"edge\" id=\"edge10\"><title>fft_8-&gt;velocity_map_9</title>\n",
       "<path d=\"M401.663,-791.697C401.002,-783.983 400.207,-774.712 399.47,-766.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"402.953,-765.769 398.612,-756.104 395.979,-766.367 402.953,-765.769\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiply_11 -->\n",
       "<g class=\"node\" id=\"node12\"><title>multiply_11</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-594\" fill=\"green\" rx=\"39.7935\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-590.3\">multiply</text>\n",
       "</g>\n",
       "<!-- fft_8&#45;&gt;multiply_11 -->\n",
       "<g class=\"edge\" id=\"edge12\"><title>fft_8-&gt;multiply_11</title>\n",
       "<path d=\"M423.29,-797.914C437.862,-788.726 456.602,-774.236 466.146,-756 488.462,-713.358 487.615,-655.621 484.621,-622.133\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"488.101,-621.754 483.601,-612.163 481.137,-622.467 488.101,-621.754\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- velocity_mask_10 -->\n",
       "<g class=\"node\" id=\"node11\"><title>velocity_mask_10</title>\n",
       "<ellipse cx=\"396.146\" cy=\"-666\" fill=\"red\" rx=\"63.0888\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"396.146\" y=\"-662.3\">velocity_mask</text>\n",
       "</g>\n",
       "<!-- velocity_map_9&#45;&gt;velocity_mask_10 -->\n",
       "<g class=\"edge\" id=\"edge11\"><title>velocity_map_9-&gt;velocity_mask_10</title>\n",
       "<path d=\"M396.899,-719.697C396.789,-711.983 396.656,-702.712 396.533,-694.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"400.033,-694.053 396.39,-684.104 393.034,-694.153 400.033,-694.053\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- velocity_mask_10&#45;&gt;multiply_11 -->\n",
       "<g class=\"edge\" id=\"edge13\"><title>velocity_mask_10-&gt;multiply_11</title>\n",
       "<path d=\"M415.86,-648.765C427.447,-639.223 442.241,-627.04 454.815,-616.684\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"457.208,-619.248 462.702,-610.189 452.758,-613.844 457.208,-619.248\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- ifft_12 -->\n",
       "<g class=\"node\" id=\"node13\"><title>ifft_12</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-522\" fill=\"green\" rx=\"27\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-518.3\">ifft</text>\n",
       "</g>\n",
       "<!-- multiply_11&#45;&gt;ifft_12 -->\n",
       "<g class=\"edge\" id=\"edge14\"><title>multiply_11-&gt;ifft_12</title>\n",
       "<path d=\"M481.146,-575.697C481.146,-567.983 481.146,-558.712 481.146,-550.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"484.646,-550.104 481.146,-540.104 477.646,-550.104 484.646,-550.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- ifft_13 -->\n",
       "<g class=\"node\" id=\"node14\"><title>ifft_13</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-450\" fill=\"green\" rx=\"27\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-446.3\">ifft</text>\n",
       "</g>\n",
       "<!-- ifft_12&#45;&gt;ifft_13 -->\n",
       "<g class=\"edge\" id=\"edge15\"><title>ifft_12-&gt;ifft_13</title>\n",
       "<path d=\"M481.146,-503.697C481.146,-495.983 481.146,-486.712 481.146,-478.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"484.646,-478.104 481.146,-468.104 477.646,-478.104 484.646,-478.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- real_14 -->\n",
       "<g class=\"node\" id=\"node15\"><title>real_14</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-378\" fill=\"green\" rx=\"27\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-374.3\">real</text>\n",
       "</g>\n",
       "<!-- ifft_13&#45;&gt;real_14 -->\n",
       "<g class=\"edge\" id=\"edge16\"><title>ifft_13-&gt;real_14</title>\n",
       "<path d=\"M481.146,-431.697C481.146,-423.983 481.146,-414.712 481.146,-406.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"484.646,-406.104 481.146,-396.104 477.646,-406.104 484.646,-406.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- butter_15 -->\n",
       "<g class=\"node\" id=\"node16\"><title>butter_15</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-306\" fill=\"red\" rx=\"31.6951\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-302.3\">butter</text>\n",
       "</g>\n",
       "<!-- real_14&#45;&gt;butter_15 -->\n",
       "<g class=\"edge\" id=\"edge17\"><title>real_14-&gt;butter_15</title>\n",
       "<path d=\"M481.146,-359.697C481.146,-351.983 481.146,-342.712 481.146,-334.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"484.646,-334.104 481.146,-324.104 477.646,-334.104 484.646,-334.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- thumbnail_16 -->\n",
       "<g class=\"node\" id=\"node17\"><title>thumbnail_16</title>\n",
       "<ellipse cx=\"377.146\" cy=\"-234\" fill=\"red\" rx=\"46.2923\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"377.146\" y=\"-230.3\">thumbnail</text>\n",
       "</g>\n",
       "<!-- butter_15&#45;&gt;thumbnail_16 -->\n",
       "<g class=\"edge\" id=\"edge18\"><title>butter_15-&gt;thumbnail_16</title>\n",
       "<path d=\"M461.094,-291.503C446.014,-281.354 425.083,-267.265 407.894,-255.696\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"409.547,-252.59 399.297,-249.909 405.639,-258.397 409.547,-252.59\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiply_17 -->\n",
       "<g class=\"node\" id=\"node18\"><title>multiply_17</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-234\" fill=\"green\" rx=\"39.7935\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-230.3\">multiply</text>\n",
       "</g>\n",
       "<!-- butter_15&#45;&gt;multiply_17 -->\n",
       "<g class=\"edge\" id=\"edge19\"><title>butter_15-&gt;multiply_17</title>\n",
       "<path d=\"M475.268,-288.055C474.45,-280.346 474.207,-271.027 474.541,-262.364\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"478.04,-262.491 475.233,-252.275 471.057,-262.012 478.04,-262.491\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- butter_15&#45;&gt;multiply_17 -->\n",
       "<g class=\"edge\" id=\"edge20\"><title>butter_15-&gt;multiply_17</title>\n",
       "<path d=\"M487.024,-288.055C487.842,-280.346 488.085,-271.027 487.751,-262.364\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"491.235,-262.012 487.059,-252.275 484.252,-262.491 491.235,-262.012\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- sta_lta_18 -->\n",
       "<g class=\"node\" id=\"node19\"><title>sta_lta_18</title>\n",
       "<ellipse cx=\"481.146\" cy=\"-162\" fill=\"red\" rx=\"34.394\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"481.146\" y=\"-158.3\">sta_lta</text>\n",
       "</g>\n",
       "<!-- multiply_17&#45;&gt;sta_lta_18 -->\n",
       "<g class=\"edge\" id=\"edge21\"><title>multiply_17-&gt;sta_lta_18</title>\n",
       "<path d=\"M481.146,-215.697C481.146,-207.983 481.146,-198.712 481.146,-190.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"484.646,-190.104 481.146,-180.104 477.646,-190.104 484.646,-190.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- thumbnail_19 -->\n",
       "<g class=\"node\" id=\"node20\"><title>thumbnail_19</title>\n",
       "<ellipse cx=\"372.146\" cy=\"-90\" fill=\"red\" rx=\"46.2923\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"372.146\" y=\"-86.3\">thumbnail</text>\n",
       "</g>\n",
       "<!-- sta_lta_18&#45;&gt;thumbnail_19 -->\n",
       "<g class=\"edge\" id=\"edge22\"><title>sta_lta_18-&gt;thumbnail_19</title>\n",
       "<path d=\"M460.13,-147.503C444.074,-137.192 421.689,-122.816 403.516,-111.146\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"405.285,-108.122 394.979,-105.664 401.502,-114.012 405.285,-108.122\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- peak_to_peak_20 -->\n",
       "<g class=\"node\" id=\"node21\"><title>peak_to_peak_20</title>\n",
       "<ellipse cx=\"498.146\" cy=\"-90\" fill=\"red\" rx=\"61.99\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"498.146\" y=\"-86.3\">peak_to_peak</text>\n",
       "</g>\n",
       "<!-- sta_lta_18&#45;&gt;peak_to_peak_20 -->\n",
       "<g class=\"edge\" id=\"edge23\"><title>sta_lta_18-&gt;peak_to_peak_20</title>\n",
       "<path d=\"M485.261,-144.055C487.154,-136.261 489.446,-126.822 491.57,-118.079\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"494.992,-118.819 493.95,-108.275 488.189,-117.167 494.992,-118.819\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- peak_to_peak_20&#45;&gt;write_witsml_21 -->\n",
       "<g class=\"edge\" id=\"edge24\"><title>peak_to_peak_20-&gt;write_witsml_21</title>\n",
       "<path d=\"M475.454,-73.1159C461.677,-63.472 443.91,-51.035 428.883,-40.5162\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"430.603,-37.4474 420.403,-34.5801 426.588,-43.1821 430.603,-37.4474\" stroke=\"black\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## All the commands used in this workflow and their default settings"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## load_data"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## butter"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Setup a Butterworth filter using scipy.signal.butter() and apply it using scipy.signal.filtfilt()"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`order` : The order for a filter calculation such as the Butterworth filter"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 5"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`type` : The type of a filter which can be lowpass, highpass, bandpass, or bandstop"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : lowpass"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`padtype` : The type of end-effect control on a filter, see scipy.signal.filtfilt"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : even"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`prf` : The pulse repetition frequency in Hz (one over the time sample rate)"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 10000"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`freq` : A frequency in Hz or a wavenumber in 1/m"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 200.0"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`axis` : The axis to apply an operation to, typically in distpy axis=0 for depth and axis=1 for time"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : -1"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## butter"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Setup a Butterworth filter using scipy.signal.butter() and apply it using scipy.signal.filtfilt()"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`order` : The order for a filter calculation such as the Butterworth filter"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 5"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`type` : The type of a filter which can be lowpass, highpass, bandpass, or bandstop"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : lowpass"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`padtype` : The type of end-effect control on a filter, see scipy.signal.filtfilt"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : even"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`prf` : The pulse repetition frequency in Hz (one over the time sample rate)"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 10000"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`freq` : A frequency in Hz or a wavenumber in 1/m"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 200.0"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`axis` : The axis to apply an operation to, typically in distpy axis=0 for depth and axis=1 for time"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : -1"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## thumbnail"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Create a thumbnail image of the current 2D processed data in the specified format."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`directory_out` : The subdirectory where results will be written"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : NONE"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`format` : The format of the picture output"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : png"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`clip_level` : The number of standard devaitions about the mean for plotting thumbnails"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 1.0"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## fft"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Compute the Fast Fourier Transform (FFT) of the data along the requested axis."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`axis` : The axis to apply an operation to, typically in distpy axis=0 for depth and axis=1 for time"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : -1"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command can be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## rms_from_fft"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Calculate the RMS energy between two frequencies."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`low_freq` : A list of low frequency values for band-pass windows in Hz"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : None"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`high_freq` : A list of high frequency values for band-pass windows in Hz"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : None"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command can be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## multiple_calcs"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Perform multiple calculations using the extra_numpy.reduced_mem() system."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`low_freq` : A list of low frequency values for band-pass windows in Hz"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : None"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`high_freq` : A list of high frequency values for band-pass windows in Hz"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : None"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`func` : Either rms_from_fft or te_from_fft"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command can be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## write_witsml"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Write out to the WITSML/FBE format, suitable for loading into viewers such as Techlog or Petrel."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`directory_out` : The subdirectory where results will be written"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : NONE"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`xaxis` : A numpy vector of distances along the fibre"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : None"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`data_style` : A string identifier for the data inside the WITSML file"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : NONE"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`low_freq` : A list of low frequency values for band-pass windows in Hz"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : None"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`high_freq` : A list of high frequency values for band-pass windows in Hz"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : None"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`labels` : A list of column headers"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## fft"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Compute the Fast Fourier Transform (FFT) of the data along the requested axis."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`axis` : The axis to apply an operation to, typically in distpy axis=0 for depth and axis=1 for time"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : -1"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command can be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## velocity_map"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Calculate the phase velocity at each pixel in a 2D FFT space."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## velocity_mask"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Construct a phase-velocity filter in 2D space. The input should be from the velocity_map command."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`min_velocity` : The minimum phase velocity"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 1400"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`max_velocity` : The maximum phase velocity"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 1600"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## multiply"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Elementwise multiply, the output data-type will be the same as that of the data entering in the in_uid. This data is multiplied by data provided in the gather_uids"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command can be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## ifft"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Compute the Inverse Fast Fourier Transform (IFFT) of the data along the requested axis."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`axis` : The axis to apply an operation to, typically in distpy axis=0 for depth and axis=1 for time"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : -1"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command can be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## ifft"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Compute the Inverse Fast Fourier Transform (IFFT) of the data along the requested axis."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`axis` : The axis to apply an operation to, typically in distpy axis=0 for depth and axis=1 for time"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : -1"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command can be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## real"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Take the real value of the input"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command can be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## butter"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Setup a Butterworth filter using scipy.signal.butter() and apply it using scipy.signal.filtfilt()"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`order` : The order for a filter calculation such as the Butterworth filter"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 5"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`type` : The type of a filter which can be lowpass, highpass, bandpass, or bandstop"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : lowpass"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`padtype` : The type of end-effect control on a filter, see scipy.signal.filtfilt"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : even"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`prf` : The pulse repetition frequency in Hz (one over the time sample rate)"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 10000"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`freq` : A frequency in Hz or a wavenumber in 1/m"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 200.0"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`axis` : The axis to apply an operation to, typically in distpy axis=0 for depth and axis=1 for time"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : -1"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## thumbnail"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Create a thumbnail image of the current 2D processed data in the specified format."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`directory_out` : The subdirectory where results will be written"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : NONE"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`format` : The format of the picture output"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : png"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`clip_level` : The number of standard devaitions about the mean for plotting thumbnails"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 1.0"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## multiply"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Elementwise multiply, the output data-type will be the same as that of the data entering in the in_uid. This data is multiplied by data provided in the gather_uids"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command can be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## sta_lta"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Short-term average (STA) divided by long-term average (LTA). This transform highlights onset and so often forms part of an automated pick or edge-detection."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`sta` : The short-term average window-length in samples"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 50"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`lta` : The long-term average window-length in samples"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 200"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## thumbnail"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Create a thumbnail image of the current 2D processed data in the specified format."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`directory_out` : The subdirectory where results will be written"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : NONE"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`format` : The format of the picture output"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : png"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`clip_level` : The number of standard devaitions about the mean for plotting thumbnails"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 1.0"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## peak_to_peak"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "The maximum peak-to-peak difference with the maximum and minimum separated by less than the defined window_length. This reduces the data from 2D (x,t) to a trace (x)."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`window_length` : The length of a filter window in samples"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : 5"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## write_witsml"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Write out to the WITSML/FBE format, suitable for loading into viewers such as Techlog or Petrel."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`directory_out` : The subdirectory where results will be written"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : NONE"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`xaxis` : A numpy vector of distances along the fibre"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : None"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`data_style` : A string identifier for the data inside the WITSML file"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : NONE"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`low_freq` : A list of low frequency values for band-pass windows in Hz"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : None"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`high_freq` : A list of high frequency values for band-pass windows in Hz"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "default : None"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "`labels` : A list of column headers"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "This command cannot be used with GPU."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import SVG, Latex, Markdown\n",
    "from graphviz import Source\n",
    "from ipywidgets import interactive\n",
    "from IPython.display import display\n",
    "\n",
    "import distpy.io_help.io_helpers as io_helpers\n",
    "import distpy.workers.strainrate2summary\n",
    "\n",
    "# build the null command set\n",
    "command_list = distpy.workers.strainrate2summary.build_command_list(myFlow)\n",
    "# pass this, together with the command list, to the graph to get the default Developer View\n",
    "dotgraph = io_helpers.dot_graph(myFlow['command_list'],command_list)\n",
    "\n",
    "\n",
    "graph = Source(' '.join(dotgraph))\n",
    "display(SVG(graph.pipe(format='svg')))\n",
    "\n",
    "# Build the command reference for this workflow\n",
    "lines=[]\n",
    "lines.append('## All the commands used in this workflow and their default settings')\n",
    "for command in command_list:\n",
    "    lines = io_helpers.command2md(command,lines)\n",
    "\n",
    "for line in lines:\n",
    "    display(Markdown(line))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Reconfiguring a flow for GPU-CPU\n",
    "\n",
    "With the diagram above we can see the processes that are GPU-enabled (green) and those which are not (red). A naive approach, which turns out to be useful in a lot of cases, is to break the workflow at each red process and replace that break-in-the-chain with a `write_npy`. This allows you to pick up the chain on a separately configured CPU node and take it from there.\n",
    "\n",
    "Alternatively you could insert a `to_gpu` and `from_gpu` at the top and bottom of each green section, if you are working with GPU-CPU hybrid nodes for your compute.\n",
    "\n",
    "Since the velocity filter is identical for every data chunk, we can avoid needless calculation, and streamline the processing for GPU, by pre-computing that filter once and storing it. The two steps used to generate the filter are then repaced by the GPU-friendly `load_data` node. This does, however introduce a read-from-disk, which is slow for GPU. As always, benchmarking is important for efficient bulk processing chains.\n",
    "\n",
    "A particular point for discussion in this workflow, is the Butterworth filter applied late in the event detection part, we can see a chain of green broken by that step. This is because [`scipy.signal.butter` is not available in cupy](https://docs-cupy.chainer.org/en/stable/reference/comparison.html). However, it is possible to define a Fourier domain filter to replace this, which could be applied between the two `ifft` commands. This is can be more efficient than transferring `from_gpu` and back `to_gpu`, although again benchmarking is the key.\n",
    "\n",
    "\n",
    "A deployment configuration for a GPU-CPU hybrid node, with that butterworth filter replaced by loading and applying a stored Fourier domain filter, is given below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"1196pt\" viewBox=\"0.00 0.00 477.29 1196.00\" width=\"477pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 1192)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" points=\"-4,4 -4,-1192 473.294,-1192 473.294,4 -4,4\" stroke=\"none\"/>\n",
       "<!-- load_data_0 -->\n",
       "<g class=\"node\" id=\"node1\"><title>load_data_0</title>\n",
       "<ellipse cx=\"167.146\" cy=\"-1170\" fill=\"red\" rx=\"46.2923\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"167.146\" y=\"-1166.3\">load_data</text>\n",
       "</g>\n",
       "<!-- butter_1 -->\n",
       "<g class=\"node\" id=\"node2\"><title>butter_1</title>\n",
       "<ellipse cx=\"113.146\" cy=\"-1098\" fill=\"red\" rx=\"31.6951\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"113.146\" y=\"-1094.3\">butter</text>\n",
       "</g>\n",
       "<!-- load_data_0&#45;&gt;butter_1 -->\n",
       "<g class=\"edge\" id=\"edge1\"><title>load_data_0-&gt;butter_1</title>\n",
       "<path d=\"M154.349,-1152.41C147.594,-1143.66 139.182,-1132.75 131.723,-1123.08\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"134.359,-1120.77 125.48,-1114.99 128.816,-1125.04 134.359,-1120.77\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- to_gpu_4 -->\n",
       "<g class=\"node\" id=\"node5\"><title>to_gpu_4</title>\n",
       "<ellipse cx=\"221.146\" cy=\"-1098\" fill=\"green\" rx=\"36.2938\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"221.146\" y=\"-1094.3\">to_gpu</text>\n",
       "</g>\n",
       "<!-- load_data_0&#45;&gt;to_gpu_4 -->\n",
       "<g class=\"edge\" id=\"edge4\"><title>load_data_0-&gt;to_gpu_4</title>\n",
       "<path d=\"M179.943,-1152.41C186.697,-1143.66 195.109,-1132.75 202.568,-1123.08\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"205.475,-1125.04 208.812,-1114.99 199.933,-1120.77 205.475,-1125.04\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- butter_2 -->\n",
       "<g class=\"node\" id=\"node3\"><title>butter_2</title>\n",
       "<ellipse cx=\"69.1459\" cy=\"-1026\" fill=\"red\" rx=\"31.6951\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"69.1459\" y=\"-1022.3\">butter</text>\n",
       "</g>\n",
       "<!-- butter_1&#45;&gt;butter_2 -->\n",
       "<g class=\"edge\" id=\"edge2\"><title>butter_1-&gt;butter_2</title>\n",
       "<path d=\"M102.941,-1080.76C97.5541,-1072.19 90.8278,-1061.49 84.7976,-1051.9\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"87.5806,-1049.75 79.2956,-1043.15 81.6542,-1053.48 87.5806,-1049.75\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- thumbnail_3 -->\n",
       "<g class=\"node\" id=\"node4\"><title>thumbnail_3</title>\n",
       "<ellipse cx=\"46.1459\" cy=\"-954\" fill=\"red\" rx=\"46.2923\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"46.1459\" y=\"-950.3\">thumbnail</text>\n",
       "</g>\n",
       "<!-- butter_2&#45;&gt;thumbnail_3 -->\n",
       "<g class=\"edge\" id=\"edge3\"><title>butter_2-&gt;thumbnail_3</title>\n",
       "<path d=\"M63.5782,-1008.05C60.9895,-1000.18 57.8485,-990.617 54.9497,-981.794\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"58.2688,-980.683 51.8221,-972.275 51.6186,-982.868 58.2688,-980.683\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- fft_5 -->\n",
       "<g class=\"node\" id=\"node6\"><title>fft_5</title>\n",
       "<ellipse cx=\"240.146\" cy=\"-1026\" fill=\"green\" rx=\"27\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"240.146\" y=\"-1022.3\">fft</text>\n",
       "</g>\n",
       "<!-- to_gpu_4&#45;&gt;fft_5 -->\n",
       "<g class=\"edge\" id=\"edge5\"><title>to_gpu_4-&gt;fft_5</title>\n",
       "<path d=\"M225.745,-1080.05C227.892,-1072.14 230.499,-1062.54 232.902,-1053.69\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"236.347,-1054.36 235.589,-1043.79 229.592,-1052.52 236.347,-1054.36\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- rms_from_fft_6 -->\n",
       "<g class=\"node\" id=\"node7\"><title>rms_from_fft_6</title>\n",
       "<ellipse cx=\"170.146\" cy=\"-954\" fill=\"green\" rx=\"59.5901\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"170.146\" y=\"-950.3\">rms_from_fft</text>\n",
       "</g>\n",
       "<!-- fft_5&#45;&gt;rms_from_fft_6 -->\n",
       "<g class=\"edge\" id=\"edge6\"><title>fft_5-&gt;rms_from_fft_6</title>\n",
       "<path d=\"M225.642,-1010.5C216.49,-1001.34 204.452,-989.306 193.927,-978.781\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"196.14,-976.044 186.594,-971.448 191.19,-980.994 196.14,-976.044\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiple_calcs_7 -->\n",
       "<g class=\"node\" id=\"node8\"><title>multiple_calcs_7</title>\n",
       "<ellipse cx=\"310.146\" cy=\"-954\" fill=\"green\" rx=\"62.2891\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"310.146\" y=\"-950.3\">multiple_calcs</text>\n",
       "</g>\n",
       "<!-- fft_5&#45;&gt;multiple_calcs_7 -->\n",
       "<g class=\"edge\" id=\"edge7\"><title>fft_5-&gt;multiple_calcs_7</title>\n",
       "<path d=\"M254.65,-1010.5C263.802,-1001.34 275.84,-989.306 286.365,-978.781\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"289.102,-980.994 293.698,-971.448 284.152,-976.044 289.102,-980.994\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- fft_11 -->\n",
       "<g class=\"node\" id=\"node12\"><title>fft_11</title>\n",
       "<ellipse cx=\"417.146\" cy=\"-954\" fill=\"green\" rx=\"27\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"417.146\" y=\"-950.3\">fft</text>\n",
       "</g>\n",
       "<!-- fft_5&#45;&gt;fft_11 -->\n",
       "<g class=\"edge\" id=\"edge12\"><title>fft_5-&gt;fft_11</title>\n",
       "<path d=\"M263.829,-1016.77C292.033,-1006.81 340.445,-989.225 381.146,-972 382.96,-971.232 384.816,-970.425 386.683,-969.596\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"388.315,-972.698 395.955,-965.358 385.405,-966.332 388.315,-972.698\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- from_gpu_8 -->\n",
       "<g class=\"node\" id=\"node9\"><title>from_gpu_8</title>\n",
       "<ellipse cx=\"176.146\" cy=\"-882\" fill=\"green\" rx=\"46.5926\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"176.146\" y=\"-878.3\">from_gpu</text>\n",
       "</g>\n",
       "<!-- rms_from_fft_6&#45;&gt;from_gpu_8 -->\n",
       "<g class=\"edge\" id=\"edge8\"><title>rms_from_fft_6-&gt;from_gpu_8</title>\n",
       "<path d=\"M171.629,-935.697C172.29,-927.983 173.085,-918.712 173.822,-910.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"177.313,-910.367 174.68,-900.104 170.339,-909.769 177.313,-910.367\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- from_gpu_9 -->\n",
       "<g class=\"node\" id=\"node10\"><title>from_gpu_9</title>\n",
       "<ellipse cx=\"295.146\" cy=\"-882\" fill=\"green\" rx=\"46.5926\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"295.146\" y=\"-878.3\">from_gpu</text>\n",
       "</g>\n",
       "<!-- multiple_calcs_7&#45;&gt;from_gpu_9 -->\n",
       "<g class=\"edge\" id=\"edge9\"><title>multiple_calcs_7-&gt;from_gpu_9</title>\n",
       "<path d=\"M306.438,-935.697C304.785,-927.983 302.799,-918.712 300.956,-910.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"304.329,-909.149 298.811,-900.104 297.484,-910.616 304.329,-909.149\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- write_witsml_10 -->\n",
       "<g class=\"node\" id=\"node11\"><title>write_witsml_10</title>\n",
       "<ellipse cx=\"274.146\" cy=\"-810\" fill=\"red\" rx=\"56.59\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"274.146\" y=\"-806.3\">write_witsml</text>\n",
       "</g>\n",
       "<!-- from_gpu_8&#45;&gt;write_witsml_10 -->\n",
       "<g class=\"edge\" id=\"edge11\"><title>from_gpu_8-&gt;write_witsml_10</title>\n",
       "<path d=\"M197.41,-865.811C210.963,-856.13 228.737,-843.435 243.766,-832.7\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"246.141,-835.305 252.244,-826.644 242.073,-829.608 246.141,-835.305\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- write_witsml_26 -->\n",
       "<g class=\"node\" id=\"node27\"><title>write_witsml_26</title>\n",
       "<ellipse cx=\"227.146\" cy=\"-18\" fill=\"red\" rx=\"56.59\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"227.146\" y=\"-14.3\">write_witsml</text>\n",
       "</g>\n",
       "<!-- from_gpu_8&#45;&gt;write_witsml_26 -->\n",
       "<g class=\"edge\" id=\"edge31\"><title>from_gpu_8-&gt;write_witsml_26</title>\n",
       "<path d=\"M176.146,-863.951C176.146,-837.292 176.146,-784.115 176.146,-739 176.146,-739 176.146,-739 176.146,-161 176.146,-118.354 196.772,-72.5195 211.79,-44.7997\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"215.004,-46.2225 216.825,-35.7853 208.893,-42.8089 215.004,-46.2225\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- from_gpu_9&#45;&gt;write_witsml_10 -->\n",
       "<g class=\"edge\" id=\"edge10\"><title>from_gpu_9-&gt;write_witsml_10</title>\n",
       "<path d=\"M290.062,-864.055C287.724,-856.261 284.892,-846.822 282.27,-838.079\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"285.554,-836.848 279.328,-828.275 278.85,-838.859 285.554,-836.848\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- data_load_12 -->\n",
       "<g class=\"node\" id=\"node13\"><title>data_load_12</title>\n",
       "<ellipse cx=\"410.146\" cy=\"-882\" fill=\"green\" rx=\"46.2923\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"410.146\" y=\"-878.3\">data_load</text>\n",
       "</g>\n",
       "<!-- fft_11&#45;&gt;data_load_12 -->\n",
       "<g class=\"edge\" id=\"edge13\"><title>fft_11-&gt;data_load_12</title>\n",
       "<path d=\"M415.416,-935.697C414.644,-927.983 413.717,-918.712 412.857,-910.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"416.334,-909.706 411.856,-900.104 409.369,-910.403 416.334,-909.706\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiply_13 -->\n",
       "<g class=\"node\" id=\"node14\"><title>multiply_13</title>\n",
       "<ellipse cx=\"425.146\" cy=\"-810\" fill=\"green\" rx=\"39.7935\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"425.146\" y=\"-806.3\">multiply</text>\n",
       "</g>\n",
       "<!-- fft_11&#45;&gt;multiply_13 -->\n",
       "<g class=\"edge\" id=\"edge14\"><title>fft_11-&gt;multiply_13</title>\n",
       "<path d=\"M434.411,-939.788C445.517,-930.137 458.983,-915.985 465.146,-900 470.901,-885.071 470.228,-879.171 465.146,-864 461.538,-853.231 454.784,-842.902 447.838,-834.269\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"450.385,-831.862 441.218,-826.552 445.073,-836.42 450.385,-831.862\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- data_load_12&#45;&gt;multiply_13 -->\n",
       "<g class=\"edge\" id=\"edge15\"><title>data_load_12-&gt;multiply_13</title>\n",
       "<path d=\"M413.777,-864.055C415.447,-856.261 417.47,-846.822 419.343,-838.079\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"422.771,-838.787 421.444,-828.275 415.926,-837.32 422.771,-838.787\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- ifft_14 -->\n",
       "<g class=\"node\" id=\"node15\"><title>ifft_14</title>\n",
       "<ellipse cx=\"425.146\" cy=\"-738\" fill=\"green\" rx=\"27\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"425.146\" y=\"-734.3\">ifft</text>\n",
       "</g>\n",
       "<!-- multiply_13&#45;&gt;ifft_14 -->\n",
       "<g class=\"edge\" id=\"edge16\"><title>multiply_13-&gt;ifft_14</title>\n",
       "<path d=\"M425.146,-791.697C425.146,-783.983 425.146,-774.712 425.146,-766.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"428.646,-766.104 425.146,-756.104 421.646,-766.104 428.646,-766.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- data_load_15 -->\n",
       "<g class=\"node\" id=\"node16\"><title>data_load_15</title>\n",
       "<ellipse cx=\"357.146\" cy=\"-666\" fill=\"green\" rx=\"46.2923\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"357.146\" y=\"-662.3\">data_load</text>\n",
       "</g>\n",
       "<!-- ifft_14&#45;&gt;data_load_15 -->\n",
       "<g class=\"edge\" id=\"edge17\"><title>ifft_14-&gt;data_load_15</title>\n",
       "<path d=\"M411.056,-722.496C402.103,-713.28 390.307,-701.136 380.032,-690.559\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"382.36,-687.932 372.881,-683.198 377.339,-692.81 382.36,-687.932\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiply_16 -->\n",
       "<g class=\"node\" id=\"node17\"><title>multiply_16</title>\n",
       "<ellipse cx=\"359.146\" cy=\"-594\" fill=\"green\" rx=\"39.7935\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"359.146\" y=\"-590.3\">multiply</text>\n",
       "</g>\n",
       "<!-- ifft_14&#45;&gt;multiply_16 -->\n",
       "<g class=\"edge\" id=\"edge18\"><title>ifft_14-&gt;multiply_16</title>\n",
       "<path d=\"M425.767,-719.986C425.764,-701.343 423.705,-671.027 412.146,-648 406.171,-636.098 396.503,-625.241 387.049,-616.497\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"389.076,-613.62 379.245,-609.672 384.468,-618.889 389.076,-613.62\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- data_load_15&#45;&gt;multiply_16 -->\n",
       "<g class=\"edge\" id=\"edge19\"><title>data_load_15-&gt;multiply_16</title>\n",
       "<path d=\"M357.64,-647.697C357.861,-639.983 358.126,-630.712 358.371,-622.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"361.87,-622.2 358.657,-612.104 354.873,-622 361.87,-622.2\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- ifft_17 -->\n",
       "<g class=\"node\" id=\"node18\"><title>ifft_17</title>\n",
       "<ellipse cx=\"359.146\" cy=\"-522\" fill=\"green\" rx=\"27\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"359.146\" y=\"-518.3\">ifft</text>\n",
       "</g>\n",
       "<!-- multiply_16&#45;&gt;ifft_17 -->\n",
       "<g class=\"edge\" id=\"edge20\"><title>multiply_16-&gt;ifft_17</title>\n",
       "<path d=\"M359.146,-575.697C359.146,-567.983 359.146,-558.712 359.146,-550.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"362.646,-550.104 359.146,-540.104 355.646,-550.104 362.646,-550.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- real_18 -->\n",
       "<g class=\"node\" id=\"node19\"><title>real_18</title>\n",
       "<ellipse cx=\"359.146\" cy=\"-450\" fill=\"green\" rx=\"27\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"359.146\" y=\"-446.3\">real</text>\n",
       "</g>\n",
       "<!-- ifft_17&#45;&gt;real_18 -->\n",
       "<g class=\"edge\" id=\"edge21\"><title>ifft_17-&gt;real_18</title>\n",
       "<path d=\"M359.146,-503.697C359.146,-495.983 359.146,-486.712 359.146,-478.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"362.646,-478.104 359.146,-468.104 355.646,-478.104 362.646,-478.104\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- from_gpu_19 -->\n",
       "<g class=\"node\" id=\"node20\"><title>from_gpu_19</title>\n",
       "<ellipse cx=\"254.146\" cy=\"-378\" fill=\"green\" rx=\"46.5926\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"254.146\" y=\"-374.3\">from_gpu</text>\n",
       "</g>\n",
       "<!-- real_18&#45;&gt;from_gpu_19 -->\n",
       "<g class=\"edge\" id=\"edge22\"><title>real_18-&gt;from_gpu_19</title>\n",
       "<path d=\"M340.374,-436.485C325.065,-426.279 303.12,-411.65 285.201,-399.703\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"287.036,-396.72 276.774,-394.085 283.153,-402.545 287.036,-396.72\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- multiply_21 -->\n",
       "<g class=\"node\" id=\"node22\"><title>multiply_21</title>\n",
       "<ellipse cx=\"359.146\" cy=\"-378\" fill=\"green\" rx=\"39.7935\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"359.146\" y=\"-374.3\">multiply</text>\n",
       "</g>\n",
       "<!-- real_18&#45;&gt;multiply_21 -->\n",
       "<g class=\"edge\" id=\"edge24\"><title>real_18-&gt;multiply_21</title>\n",
       "<path d=\"M353.306,-432.411C352.443,-424.507 352.194,-414.852 352.558,-405.935\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"356.049,-406.179 353.266,-395.956 349.067,-405.683 356.049,-406.179\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- real_18&#45;&gt;multiply_21 -->\n",
       "<g class=\"edge\" id=\"edge25\"><title>real_18-&gt;multiply_21</title>\n",
       "<path d=\"M364.986,-432.411C365.848,-424.507 366.098,-414.852 365.734,-405.935\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"369.225,-405.683 365.025,-395.956 362.243,-406.179 369.225,-405.683\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- thumbnail_20 -->\n",
       "<g class=\"node\" id=\"node21\"><title>thumbnail_20</title>\n",
       "<ellipse cx=\"250.146\" cy=\"-306\" fill=\"red\" rx=\"46.2923\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"250.146\" y=\"-302.3\">thumbnail</text>\n",
       "</g>\n",
       "<!-- from_gpu_19&#45;&gt;thumbnail_20 -->\n",
       "<g class=\"edge\" id=\"edge23\"><title>from_gpu_19-&gt;thumbnail_20</title>\n",
       "<path d=\"M253.157,-359.697C252.716,-351.983 252.187,-342.712 251.695,-334.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"255.188,-333.888 251.123,-324.104 248.2,-334.288 255.188,-333.888\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- from_gpu_22 -->\n",
       "<g class=\"node\" id=\"node23\"><title>from_gpu_22</title>\n",
       "<ellipse cx=\"361.146\" cy=\"-306\" fill=\"green\" rx=\"46.5926\" ry=\"18\" stroke=\"green\"/>\n",
       "<text font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"361.146\" y=\"-302.3\">from_gpu</text>\n",
       "</g>\n",
       "<!-- multiply_21&#45;&gt;from_gpu_22 -->\n",
       "<g class=\"edge\" id=\"edge26\"><title>multiply_21-&gt;from_gpu_22</title>\n",
       "<path d=\"M359.64,-359.697C359.861,-351.983 360.126,-342.712 360.371,-334.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"363.87,-334.2 360.657,-324.104 356.873,-334 363.87,-334.2\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- sta_lta_23 -->\n",
       "<g class=\"node\" id=\"node24\"><title>sta_lta_23</title>\n",
       "<ellipse cx=\"349.146\" cy=\"-234\" fill=\"red\" rx=\"34.394\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"349.146\" y=\"-230.3\">sta_lta</text>\n",
       "</g>\n",
       "<!-- from_gpu_22&#45;&gt;sta_lta_23 -->\n",
       "<g class=\"edge\" id=\"edge27\"><title>from_gpu_22-&gt;sta_lta_23</title>\n",
       "<path d=\"M358.18,-287.697C356.857,-279.983 355.268,-270.712 353.794,-262.112\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"357.217,-261.369 352.078,-252.104 350.318,-262.552 357.217,-261.369\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- thumbnail_24 -->\n",
       "<g class=\"node\" id=\"node25\"><title>thumbnail_24</title>\n",
       "<ellipse cx=\"302.146\" cy=\"-162\" fill=\"red\" rx=\"46.2923\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"302.146\" y=\"-158.3\">thumbnail</text>\n",
       "</g>\n",
       "<!-- sta_lta_23&#45;&gt;thumbnail_24 -->\n",
       "<g class=\"edge\" id=\"edge28\"><title>sta_lta_23-&gt;thumbnail_24</title>\n",
       "<path d=\"M338.245,-216.765C332.515,-208.23 325.365,-197.582 318.944,-188.019\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"321.794,-185.985 313.314,-179.633 315.983,-189.887 321.794,-185.985\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- peak_to_peak_25 -->\n",
       "<g class=\"node\" id=\"node26\"><title>peak_to_peak_25</title>\n",
       "<ellipse cx=\"278.146\" cy=\"-90\" fill=\"red\" rx=\"61.99\" ry=\"18\" stroke=\"red\"/>\n",
       "<text fill=\"white\" font-family=\"Times New Roman,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"278.146\" y=\"-86.3\">peak_to_peak</text>\n",
       "</g>\n",
       "<!-- thumbnail_24&#45;&gt;peak_to_peak_25 -->\n",
       "<g class=\"edge\" id=\"edge29\"><title>thumbnail_24-&gt;peak_to_peak_25</title>\n",
       "<path d=\"M296.336,-144.055C293.635,-136.176 290.357,-126.617 287.332,-117.794\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"290.623,-116.6 284.069,-108.275 284.001,-118.87 290.623,-116.6\" stroke=\"black\"/>\n",
       "</g>\n",
       "<!-- peak_to_peak_25&#45;&gt;write_witsml_26 -->\n",
       "<g class=\"edge\" id=\"edge30\"><title>peak_to_peak_25-&gt;write_witsml_26</title>\n",
       "<path d=\"M265.8,-72.055C259.661,-63.6287 252.121,-53.2798 245.336,-43.9663\" fill=\"none\" stroke=\"black\"/>\n",
       "<polygon fill=\"black\" points=\"248.095,-41.8104 239.378,-35.789 242.438,-45.9324 248.095,-41.8104\" stroke=\"black\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "myFlowGPU = {\n",
    "\"document\" : 0,\n",
    "\"description\" : \"A more complex example of a DAS processing flow\",\n",
    "\"command_list\" :\n",
    "[\n",
    " { \"name\" : \"butter\",         \"uid\" :  1, \"in_uid\" : 0, \"type\" : \"lowpass\", \"freq\" : 200 },\n",
    " { \"name\" : \"butter\",         \"uid\" :  2, \"in_uid\" : 1, \"type\" : \"highpass\", \"freq\" : 5 },\n",
    " { \"name\" : \"thumbnail\",      \"uid\" :  3, \"in_uid\" : 2, \"directory_out\" : \"png\" },\n",
    " { \"name\" : \"to_gpu\",         \"uid\" :  4, \"in_uid\" : 0 },    \n",
    " { \"name\" : \"fft\",            \"uid\" :  5, \"in_uid\" :  4, \"axis\" : 1 },\n",
    " { \"name\" : \"rms_from_fft\",   \"uid\" :  6, \"in_uid\" :  5, \"low_freq\" : 0, \"high_freq\" : -1 },\n",
    " { \"name\" : \"multiple_calcs\", \"uid\" :  7, \"in_uid\" :  5,   \"func\" : \"te_from_fft\",     \"low_freq\" : [200,600,1000], \"high_freq\" : [-1,-1,-1] }, \n",
    " { \"name\" : \"from_gpu\",       \"uid\" :  8, \"in_uid\" :  6 },\n",
    " { \"name\" : \"from_gpu\",       \"uid\" :  9, \"in_uid\" :  7 },\n",
    " { \"name\" : \"write_witsml\",   \"uid\" : 10, \"in_uid\" :  9, \"directory_out\" : \"NoiseLog\", \"low_freq\" : [200,600,1000], \"high_freq\" : [-1,-1,-1],  \"gather_uids\" : [8], \"data_style\" : \"NoiseLog\" },\n",
    " { \"name\" : \"fft\",            \"uid\" : 11, \"in_uid\" :  5, \"axis\" : 0},\n",
    " { \"name\" : \"data_load\",      \"uid\" : 12, \"in_uid\" : 11, \"filename\" : \"filters/velocity.npy\"},\n",
    " { \"name\" : \"multiply\",       \"uid\" : 13, \"in_uid\" : 11, \"gather_uids\" : [12] },\n",
    " { \"name\" : \"ifft\",           \"uid\" : 14, \"in_uid\" : 13, \"axis\" : 0},\n",
    " { \"name\" : \"data_load\",      \"uid\" : 15, \"in_uid\" : 14, \"filename\" : \"filters/butter.npy\"},\n",
    " { \"name\" : \"multiply\",       \"uid\" : 16, \"in_uid\" : 14, \"gather_uids\" : [15] },\n",
    " { \"name\" : \"ifft\",           \"uid\" : 17, \"in_uid\" : 16, \"axis\" : 1},\n",
    " { \"name\" : \"real\",           \"uid\" : 18, \"in_uid\" : 17},\n",
    " { \"name\" : \"from_gpu\",       \"uid\" : 19, \"in_uid\" : 18 },\n",
    " { \"name\" : \"thumbnail\",      \"uid\" : 20, \"in_uid\" : 19, \"directory_out\" : \"filtered_png\", \"format\" : \"png\" },\n",
    " { \"name\" : \"multiply\",       \"uid\" : 21, \"in_uid\" : 18, \"gather_uids\" : [18] },\n",
    " { \"name\" : \"from_gpu\",       \"uid\" : 22, \"in_uid\" : 21 },\n",
    " { \"name\" : \"sta_lta\",        \"uid\" : 23, \"in_uid\" : 22, \"sta\" : 50, \"lta\" : 200},\n",
    " { \"name\" : \"thumbnail\",      \"uid\" : 24, \"in_uid\" : 23, \"directory_out\" : \"events_png\", \"format\" : \"png\" },\n",
    " { \"name\" : \"peak_to_peak\",   \"uid\" : 25, \"in_uid\" : 24, \"window_length\" : 200},\n",
    " { \"name\" : \"write_witsml\",   \"uid\" : 26, \"in_uid\" : 25, \"directory_out\" : \"p2p\", \"low_freq\" : [0], \"high_freq\" : [1],  \"gather_uids\" : [8], \"data_style\" : \"p2p\" }\n",
    "]\n",
    "}\n",
    "\n",
    "# build the null command set\n",
    "command_list = distpy.workers.strainrate2summary.build_command_list(myFlowGPU)\n",
    "# pass this, together with the command list, to the graph to get the default Developer View\n",
    "dotgraph = io_helpers.dot_graph(myFlowGPU['command_list'],command_list)\n",
    "\n",
    "\n",
    "graph = Source(' '.join(dotgraph))\n",
    "display(SVG(graph.pipe(format='svg')))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Summary\n",
    "\n",
    "In this tutorial we learned how to:\n",
    "1. Autodocument a flow and how to customize self-documented flows\n",
    "2. Create the developer view for analysing an existing flow\n",
    "3. How to reconfigure flows for GPU-CPU\n",
    "\n",
    "Once you have the configuration, deployment can be delivered via the [Docker container](https://github.com/Schlumberger/distpy/wiki/User-Tutorial-:-Docker-and-Kubernetes), but there are plenty of other alternatives. Of course, testing and benchmarking are important, GPU enabled workflows can be fast provided the additional I/O doesn't outweigh the performance gains."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
